/*
 * Copyright (c) 2015. 石头哥哥
 */

package com.comom.manager.kit;

import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by 石头哥哥 on 15/9/28.
 * PROJECT_NAME: mengchongdoc
 * PACKAGE_NAME: com.mengchong.server.kit
 * COMMENT : 过滤铭感词汇
 * spring 默认 单例
 */
@Service
public class KeywordFilter {

    /**
     * 根节点   only read
     */
    private TreeNode rootNode = new TreeNode();


    /**
     * 关键词编码
     */
    private String charset = "utf-8";

    /**
     * 初始化 key words
     */
    @SuppressWarnings({"RedundantStringToString", "ConstantConditions"})
    @PostConstruct
    private void initKeyWords() {
        StringBuilder patternBuf = new StringBuilder();
        try {
            String osName = System.getProperties().getProperty("os.name"); //操作系统名称
            //init oss config
            String configFileName;
            if (osName.contains("Mac")) {
                //mac os
                configFileName = this.getClass().getClassLoader().getResource("")
                        .getPath().toString().replace("WEB-INF/classes/", "WEB-INF/res/keywords.txt");
            } else {
                configFileName = this.getClass().getClassLoader().getResource("")
                        .getPath().toString().replace("classes/", "res/keywords.txt");
            }
            BufferedReader br = new BufferedReader(new FileReader(configFileName));
            String temp;
            while ((temp = br.readLine()) != null && !temp.equals("")) {
                patternBuf.append(temp).append(";");
            }
            br.close();

            // init node
            String keywords[] = patternBuf.toString().split(";");
            for (String keyword : keywords) {
                if (keyword == null) continue;
                keyword = keyword.trim();
                byte[] bytes = keyword.getBytes(charset);
                TreeNode tempNode = rootNode;
                for (int i = 0; i < bytes.length; i++) {
                    int index = bytes[i] & 0xff;
                    TreeNode node = tempNode.getSubNode(index);
                    if (node == null) {
                        node = new TreeNode();
                        tempNode.setSubNode(index, node);
                    }
                    tempNode = node;
                    if (i == bytes.length - 1) {
                        tempNode.setKeywordEnd(true);
                    }
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    /**
     * 返回过滤之后的 字符串
     *
     * @param message
     * @return
     */
    public String filter(String message) {
        try {
            byte[] bytes = message.getBytes(charset);
            TreeNode tempNode = rootNode;
            int rollback = 0;
            int position = 0;
            while (position < bytes.length) {
                int index = bytes[position] & 0xFF;
                tempNode = tempNode.getSubNode(index);
                if (tempNode == null) {
                    position = position - rollback;
                    rollback = 0;
                    tempNode = rootNode;// only read
                } else if (tempNode.isKeywordEnd()) {
                    for (int i = 0; i <= rollback; i++) {
                        bytes[position - i] = 42;
                    }
                    rollback = 1;
                } else {
                    rollback++;
                }
                position++;
            }
            String result = null;
            try {
                result = new String(bytes, "utf-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }


    public void setCharset(String charset) {
        this.charset = charset;
    }

    /**
     *
     */
    class TreeNode {

        private static final int NODE_LEN = 256;

        /**
         * true 关键词的终结 ； false 继续
         */
        private boolean end = false;

        private List<TreeNode> subNodes = new ArrayList<TreeNode>(NODE_LEN);

        public TreeNode() {
            for (int i = 0; i < NODE_LEN; i++) {
                subNodes.add(i, null);
            }
        }

        /**
         * 向指定位置添加节点树
         *
         * @param index
         * @param node
         */
        public void setSubNode(int index, TreeNode node) {
            subNodes.set(index, node);
        }

        public TreeNode getSubNode(int index) {
            return subNodes.get(index);
        }


        public boolean isKeywordEnd() {
            return end;
        }

        public void setKeywordEnd(boolean end) {
            this.end = end;
        }
    }


}
